package com.zeratul.common.mybatis.core.page.aop;

import com.zeratul.common.core.result.page.BaseResult;
import com.zeratul.common.mybatis.core.page.entity.Page;
import com.zeratul.common.mybatis.core.page.utils.ZtPages;
import com.zeratul.web.utils.ServletUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Value;

import java.util.HashMap;
import java.util.Map;


/**
 * Controller层的分页拦截处理的AOP
 */
@Aspect
public class WebPageAop {

    @Value("${kenplugin.page.key.num:pageNum}")
    private String pNum;
    @Value("${kenplugin.page.key.size:pageSize}")
    private String pSize;
    @Value("${kenplugin.page.key.total:total}")
    private String pTotal;
    @Value("${kenplugin.page.key.count:count}")
    private String pCount;

    /**
     * 被@Paging注解标记的方法，会被AOP拦截
     * @return
     */
    @Around("@within(org.springframework.web.bind.annotation.RestController) || @within(org.springframework.stereotype.Controller)")
    public Object pageHandler(ProceedingJoinPoint joinPoint) throws Throwable {
        //获得请求参数
        String pageNum = ServletUtils.getParameterOrHeader(pNum);
        String pageSize = ServletUtils.getParameterOrHeader(pSize);

        //封装Page对象
        if (pageNum != null && pageSize != null) {
            //缓存到ThreadLocal中
            ZtPages.setPage(Integer.valueOf(pageNum), Integer.valueOf(pageSize));
        }

        try {
            //放行请求
            Object result = joinPoint.proceed();
            //获取请求线程中Page对象
            Page page = ZtPages.getPage();
            if (page != null && result instanceof BaseResult r) {
                //如果有分页信息，将page分页设置到返回对象上
                Map<String, Integer> pageMap = new HashMap<>();
                pageMap.put(pNum, page.getPageNum());
                pageMap.put(pSize, page.getPageSize());
                pageMap.put(pTotal, page.getTotal());
                pageMap.put(pCount, page.getCount());
                r.setPage(pageMap);
            }
            return result;
        } finally {
            //移除Page对象
            ZtPages.clearPage();
        }


    }
}
